// Package prometheus
// Created by GoLand
// @User: lenora
// @Date: 2024/7/25
// @Time: 14:58

package prometheus

import (
	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"strconv"
	"time"
)

type Builder struct {
	Namespace  string
	Subsystem  string
	Name       string
	InstanceId string
}

func NewBuilder(namespace string, subsystem string, name string, instanceId string) *Builder {
	return &Builder{Namespace: namespace, Subsystem: subsystem, Name: name, InstanceId: instanceId}
}

func (b *Builder) BuildResponseTime() gin.HandlerFunc {
	labels := []string{"method", "pattern", "status"}
	vector := prometheus.NewSummaryVec(prometheus.SummaryOpts{
		//namespace,subsystem,name这三个字段值不能包含除"_"以外的特殊字符
		Namespace: b.Namespace,
		Subsystem: b.Subsystem,
		Name:      b.Name + "_resp_time",
		Help:      "i am aaa",
		ConstLabels: map[string]string{
			//实例id,分布式环境下区分是哪个实例执行
			"instance_id": b.InstanceId,
		},
		Objectives: map[float64]float64{
			0.5:   0.01,
			0.75:  0.01,
			0.9:   0.01,
			0.99:  0.001,
			0.999: 0.0001,
		},
	}, labels)
	prometheus.MustRegister(vector)
	return func(context *gin.Context) {
		start := time.Now()
		defer func() {
			//上报数据至prometheus
			duration := time.Since(start)
			method := context.Request.Method
			pattern := context.FullPath()
			status := context.Writer.Status()
			vector.WithLabelValues(method, pattern, strconv.Itoa(status)).Observe(float64(duration.Milliseconds()))
		}()
		context.Next()
	}
}

func (b *Builder) BuildActiveRequest() gin.HandlerFunc {
	active := prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: b.Namespace,
		Subsystem: b.Subsystem,
		Name:      b.Name + "_active_reqs",
		ConstLabels: map[string]string{
			"instance_id": b.InstanceId,
		},
	})
	prometheus.MustRegister(active)
	return func(context *gin.Context) {
		active.Inc()
		defer active.Dec()
		context.Next()
	}
}
